package utils

import (
	"fmt"
	"net"
	"os"
)

func GetIPs() (ips []string) {
	interfaceAddr, err := net.InterfaceAddrs()
	if err != nil {
		fmt.Printf("fail to get net interface addrs: %v", err)
		return ips
	}

	for _, address := range interfaceAddr {
		ipNet, isValidIpNet := address.(*net.IPNet)
		if isValidIpNet && !ipNet.IP.IsLoopback() {
			if ipNet.IP.To4() != nil {
				ips = append(ips, ipNet.IP.String())
			}
		}
	}
	return ips
}

func GetPID() {
	os.Getpid()
}

func GetMacAddr() []byte {
	netInterface, err := GetIPv4MacAddr()
	if err != nil {
		fmt.Printf("fail to get net interfaces: %v", err)
		return []byte{}
	}
	return netInterface.HardwareAddr
}

func GetIPv4MacAddr() (*net.Interface, error) {
	netInterfaces, err := net.Interfaces()
	if err != nil {
		fmt.Printf("fail to get net interfaces: %v", err)
		return nil, err
	}
	for _, netInterface := range netInterfaces {
		if netInterface.Flags&net.FlagUp == 0 {
			continue // interface down
		}
		if netInterface.Flags&net.FlagLoopback != 0 {
			continue // loopback interface
		}
		addrs, err := netInterface.Addrs()
		if err != nil {
			continue
		}
		for _, addr := range addrs {
			var ip net.IP
			switch v := addr.(type) {
			case *net.IPNet:
				ip = v.IP
			case *net.IPAddr:
				ip = v.IP
			}
			if ip == nil || ip.IsLoopback() {
				continue
			}
			if ip.To4() != nil {
				return &netInterface, nil
			}
		}
	}
	return nil, nil
}

func MacAddrToInt(macByte []byte, maxDataCenterId int64) int64 {
	macByteLen := len(macByte)
	if macByteLen == 0 {
		return 1
	}
	id := int64(0)
	id = ((0x000000FF & int64(macByte[macByteLen-1])) | (0x0000FF00 & int64(macByte[macByteLen-2]) << 8)) >> 6
	id = id % maxDataCenterId
	return id
}
